/**
 * @file usr_common.c
 * @author zcj (605607217@qq.com)
 * @brief
 * @version ecu-中控
 * @date 2023-11-06
 *
 * @copyright Copyright (c) 2023
 *
 */

#include "main.h"

DEV_INFO_T *g_dev_info = NULL;
DEV_LTE_T g_dev_lte = {0};
DEV_BSLOC_T g_dev_bsloc = {0};
EBIKE_STATE_T g_ebike_status = {0};

/**
 * @brief Get the reset reason object
 *
 * @return int
 * @version ecu4.0.2
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 * @copyright Copyright (c) 2023
 */
int get_reset_reason(void)
{
    ResetReasonInit();
    int ret = luat_pm_get_poweron_reason();

    switch (ret)
    {
    case LUAT_PM_POWERON_REASON_NORMAL:
        usr_log("powerkey或者上电开机");
        break;
    case LUAT_PM_POWERON_REASON_FOTA:
        usr_log("充电或者AT指令下载完成后开机");
        break;
    case LUAT_PM_POWERON_REASON_SWRESET:
        usr_log("软件重启");
        break;
    case LUAT_PM_POWERON_REASON_EXCEPTION:
        usr_log("异常重启");
        break;
    case LUAT_PM_POWERON_REASON_WDT:
        usr_log("内部看门狗重启");
        break;
    case LUAT_PM_POWERON_REASON_EXTERNAL:
        usr_log("外部重启");
        break;
    default:
        usr_log("未知原因");
        break;
    }
    return ret;
}

/**
 * @brief crc32
 *
 * @param data
 * @param size
 * @param poly
 * @return uint32_t
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
// uint32_t crc32_compute(const void *data, size_t size, uint32_t poly)
// {
//     uint32_t crc = 0xFFFFFFFF;
//     const uint8_t *buffer = (const uint8_t *)data;
//     size_t i;
//     for (i = 0; i < size; ++i)
//     {
//         crc ^= buffer[i];
//         for (int j = 0; j < 8; ++j)
//         {
//             if (crc & 1)
//             {
//                 crc = (crc >> 1) ^ poly;
//             }
//             else
//             {
//                 crc = crc >> 1;
//             }
//         }
//     }
//     return crc ^ 0xFFFFFFFF;
// }

/**
 * @brief 初始化设备参数
 *
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
void dev_param_init(void)
{
    /*1.update g_dev_info*/
    g_dev_info = (DEV_INFO_T *)malloc(sizeof(DEV_INFO_T));
    memset(g_dev_info->data, 0, sizeof(DEV_INFO_T));
    // luat_flash_read(g_dev_info->data, DEVICE_INFO_ADDR, sizeof(DEV_INFO_T));
    // uint32_t crc = crc32_compute((uint8_t *)(g_dev_info->data + sizeof(uint32_t)), sizeof(DEV_INFO_T) - sizeof(uint32_t), POLYNOMIAL);
    luat_rtos_mutex_create(&g_dev_info->info.mutex);
    // if (crc != g_dev_info->info.crc)
    // {
        /*初始化设备信息*/
    memset(g_dev_info->data, 0, sizeof(DEV_INFO_T) - sizeof(luat_rtos_mutex_t));
 
    //}
    sprintf(g_dev_info->info.product_id, "%s", PRODUCT_ID);
    sprintf(g_dev_info->info.build_time, "%s%s", __DATE__, __TIME__);
    sprintf(g_dev_info->info.ver_hard, "%s", VERSION_HARD);
    sprintf(g_dev_info->info.ver_4g, "%s", VERSION_4G);

    sprintf(g_dev_info->info.addr,"%s",MQTT_HOST);
    g_dev_info->info.port=MQTT_PORT;

    g_dev_info->info.move_up_cycle=15;
    g_dev_info->info.stop_up_cycle=600;
    g_dev_info->info.online_flag=true;
    /*2.update starup reason*/
    g_dev_info->info.startup_reason = get_reset_reason(); 
}

void ebike_param_init(void)
{
    luat_rtos_mutex_create(&g_ebike_status.mutex);

    /*default no orders*/
     g_ebike_status.work_statu = V_STOP; //上电默认锁车状态   
     g_ebike_status.bike_locked = V_ON;//
     g_ebike_status.acc_statu = V_OFF;//
     g_ebike_status.move_flag = V_OFF;//
     g_ebike_status.anti_theft = V_OFF;//
     g_ebike_status.sleep.status = V_OFF;//
     g_ebike_status.qry_status = V_OFF;//
}

// /**
//  * @brief app init
//  * 1.dev param init(include dev info and mqtt server)
//  * 2.ebike param init
//  * 3.hard init
//  * @author zcj (605607217@qq.com)
//  * @date 2023-11-06
//  */
void usr_app_init(void)
{
    dev_param_init();
    ebike_param_init();
    hard_ware_init();
}

/**
 * @brief Get the ver 4g object
 *
 * @param dev
 * @return char*
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
char *get_ver_4g(DEV_INFO_T *dev)
{
    luat_rtos_mutex_lock(dev->info.mutex, LUAT_WAIT_FOREVER);
    char *ver = dev->info.ver_4g;
    luat_rtos_mutex_unlock(dev->info.mutex);
    return ver;
}

char *get_mqtt_addr(DEV_INFO_T *dev)
{
    luat_rtos_mutex_lock(dev->info.mutex, LUAT_WAIT_FOREVER);
    char *addr = dev->info.addr;
    luat_rtos_mutex_unlock(dev->info.mutex);
    return addr;
}
char *get_mqtt_port(DEV_INFO_T *dev)
{
    luat_rtos_mutex_lock(dev->info.mutex, LUAT_WAIT_FOREVER);
    char *port = dev->info.port;
    luat_rtos_mutex_unlock(dev->info.mutex);
    return port;
}
/**
 * @brief Get the ver hard object
 *
 * @param dev
 * @return char*
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
char *get_ver_hard(DEV_INFO_T *dev)
{
    luat_rtos_mutex_lock(dev->info.mutex, LUAT_WAIT_FOREVER);
    char *ver = dev->info.ver_hard;
    luat_rtos_mutex_unlock(dev->info.mutex);
    return ver;
}

/**
 * @brief Get the startup reason object
 *
 * @param dev
 * @return LUAT_PM_POWERON_REASON_E
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
LUAT_PM_POWERON_REASON_E get_startup_reason(DEV_INFO_T *dev)
{
    luat_rtos_mutex_lock(dev->info.mutex, LUAT_WAIT_FOREVER);
    LUAT_PM_POWERON_REASON_E reason = dev->info.startup_reason;
    luat_rtos_mutex_unlock(dev->info.mutex);
    return reason;
}

/**
 * @brief Get the startup ts object
 *
 * @param dev
 * @return time_t
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
time_t get_startup_ts(DEV_INFO_T *dev)
{
    luat_rtos_mutex_lock(dev->info.mutex, LUAT_WAIT_FOREVER);
    time_t ts = dev->info.startup_ts;
    luat_rtos_mutex_unlock(dev->info.mutex);
    return ts;
}

/**
 * @brief Set the startup ts object
 *
 * @param dev
 * @param ts
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
void set_startup_ts(DEV_INFO_T *dev, time_t ts)
{
    luat_rtos_mutex_lock(dev->info.mutex, LUAT_WAIT_FOREVER);
    dev->info.startup_ts = ts;
    luat_rtos_mutex_unlock(dev->info.mutex);
}

/**
 * @brief Get the real ts object
 *
 * @param dev
 * @return time_t
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
time_t get_real_ts(DEV_INFO_T *dev)
{
    luat_rtos_mutex_lock(dev->info.mutex, LUAT_WAIT_FOREVER);
    time_t ts = dev->info.real_ts;
    luat_rtos_mutex_unlock(dev->info.mutex);
    return ts;
}

/**
 * @brief Set the real ts object
 *
 * @param dev
 * @param ts
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
void set_real_ts(DEV_INFO_T *dev, time_t ts)
{
    luat_rtos_mutex_lock(dev->info.mutex, LUAT_WAIT_FOREVER);
    dev->info.real_ts = ts;
    luat_rtos_mutex_unlock(dev->info.mutex);
}





void set_ebike_vin(EBIKE_STATE_T *ebike,uint32_t vin)
{
    luat_rtos_mutex_lock(ebike->mutex, LUAT_WAIT_FOREVER);
    ebike->vin = vin;
    luat_rtos_mutex_unlock(ebike->mutex);
}

void set_ebike_temp(EBIKE_STATE_T *ebike,uint8_t temp)
{
    luat_rtos_mutex_lock(ebike->mutex, LUAT_WAIT_FOREVER);
    ebike->temp = temp;
    luat_rtos_mutex_unlock(ebike->mutex);
}

uint32_t get_ebike_vin(EBIKE_STATE_T *ebike)
{
    luat_rtos_mutex_lock(ebike->mutex, LUAT_WAIT_FOREVER);
    uint32_t vin = ebike->vin;
    luat_rtos_mutex_unlock(ebike->mutex);
    return vin;
}

uint8_t get_ebike_temp(EBIKE_STATE_T *ebike)
{
    luat_rtos_mutex_lock(ebike->mutex, LUAT_WAIT_FOREVER);
    uint8_t temp = ebike->temp;
    luat_rtos_mutex_unlock(ebike->mutex);
    return temp;
}
uint8_t get_ebike_rules(EBIKE_STATE_T *ebike)
{
    luat_rtos_mutex_lock(ebike->mutex, LUAT_WAIT_FOREVER);
    uint8_t rules=ebike->rules;
    luat_rtos_mutex_unlock(ebike->mutex);
    return rules;
}
void set_ebike_rules(EBIKE_STATE_T *ebike,CHANGE_STATE_T status)
{
    luat_rtos_mutex_lock(ebike->mutex, LUAT_WAIT_FOREVER);
    if (status==NO_CHANGE)
    {
       ebike->rules=0x00;
    }
    else
    {
        SET1_BIT(ebike->rules,status);
    }    
    luat_rtos_mutex_unlock(ebike->mutex);
}
/**
 * @brief Set the ebike state info object
 *
 * @param ebike
 * @param ebike_info
 * @param state
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
void set_ebike_state_info(EBIKE_STATE_T *ebike, EBIKE_STATE_INFO_E ebike_info, SWITCH_NUM_E state)
{
    luat_rtos_mutex_lock(ebike->mutex, LUAT_WAIT_FOREVER);
    switch (ebike_info)
    {
    
    case ACC_STATUS:
        ebike->acc_statu = state;
        break;
    case BIKE_LOCKED:
        ebike->bike_locked = state;
        break;
    case ANTI_THEFT:
        ebike->anti_theft = state;
        break;
    case MOVE_FLAG:
        ebike->move_flag = state;
        break;
    case POWER_STATUS:
        ebike->power_f = state; 
        break;
    case WORK_STATUS:
        ebike->work_statu=state;
        break;
    case QRY_STATUS:
        ebike->qry_status = state;
        break;
    case GPS_STATUS:
        ebike->gnss_f=state;
        break;
    default:
        break;
    }
    luat_rtos_mutex_unlock(ebike->mutex);

}

/**
 * @brief Get the ebike state info object、
 *
 * @param ebike
 * @param ebike_info
 * @return SWITCH_NUM_E
 * @author zcj (605607217@qq.com)
 * @date 2023-11-06
 */
SWITCH_NUM_E get_ebike_state_info(EBIKE_STATE_T *ebike, EBIKE_STATE_INFO_E ebike_info)
{
    SWITCH_NUM_E state;
    luat_rtos_mutex_lock(ebike->mutex, LUAT_WAIT_FOREVER);
    switch (ebike_info)
    {
    case WORK_STATUS:
        state = ebike->work_statu;
        break;
    case ACC_STATUS:
        state = ebike->acc_statu;
        break;
    case BIKE_LOCKED:
        state = ebike->bike_locked;
        break;
    case ANTI_THEFT:
        state = ebike->anti_theft;
        break;
    case MOVE_FLAG:
        state = ebike->move_flag;
        break;
    case POWER_STATUS:
        state = ebike->power_f;
        break;
    case QRY_STATUS:
        state = ebike->qry_status;
        break;
    case GPS_STATUS:
        state = ebike->gnss_f;
        break;
    default:  state = 0;
        break;
    }
    luat_rtos_mutex_unlock(ebike->mutex);
    return state;
}
